{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Installazione di Transformers\n",
    "! pip install transformers datasets evaluate accelerate\n",
    "# Per installare dalla fonte invece dell'ultima versione rilasciata, commenta il comando sopra e\n",
    "# rimuovi la modalità commento al comando seguente.\n",
    "# ! pip install git+https://github.com/huggingface/transformers.git"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Modelli multilingue per l'inferenza"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ci sono diversi modelli multilingue in 🤗 Transformers, e il loro utilizzo per l'inferenza differisce da quello dei modelli monolingua. Non *tutti* gli utilizzi dei modelli multilingue sono però diversi. Alcuni modelli, come [google-bert/bert-base-multilingual-uncased](https://huggingface.co/google-bert/bert-base-multilingual-uncased), possono essere usati come un modello monolingua. Questa guida ti mostrerà come utilizzare modelli multilingue che utilizzano un modo diverso per fare l'inferenza."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## XLM"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "XLM ha dieci diversi checkpoint, di cui solo uno è monolingua. I nove checkpoint rimanenti possono essere suddivisi in due categorie: i checkpoint che utilizzano i language embeddings e quelli che non li utilizzano."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### XLM con language embeddings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I seguenti modelli XLM utilizzano gli embeddings linguistici per specificare la lingua utilizzata per l'inferenza:\n",
    "\n",
    "- `FacebookAI/xlm-mlm-ende-1024` (Modellazione mascherata del linguaggio (Masked language modeling, in inglese), Inglese-Tedesco)\n",
    "- `FacebookAI/xlm-mlm-enfr-1024` (Modellazione mascherata del linguaggio, Inglese-Francese)\n",
    "- `FacebookAI/xlm-mlm-enro-1024` (Modellazione mascherata del linguaggio, Inglese-Rumeno)\n",
    "- `FacebookAI/xlm-mlm-xnli15-1024` (Modellazione mascherata del linguaggio, lingue XNLI)\n",
    "- `FacebookAI/xlm-mlm-tlm-xnli15-1024` (Modellazione mascherata del linguaggio + traduzione, lingue XNLI)\n",
    "- `FacebookAI/xlm-clm-enfr-1024` (Modellazione causale del linguaggio, Inglese-Francese)\n",
    "- `FacebookAI/xlm-clm-ende-1024` (Modellazione causale del linguaggio, Inglese-Tedesco)\n",
    "\n",
    "Gli embeddings linguistici sono rappresentati come un tensore delle stesse dimensioni dell' `input_ids` passato al modello. I valori in questi tensori dipendono dal linguaggio usato e sono identificati dagli attributi `lang2id` e `id2lang` del tokenizer.\n",
    "\n",
    "In questo esempio, carica il checkpoint `FacebookAI/xlm-clm-enfr-1024` (Modellazione causale del linguaggio, Inglese-Francese):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "from transformers import XLMTokenizer, XLMWithLMHeadModel\n",
    "\n",
    "tokenizer = XLMTokenizer.from_pretrained(\"FacebookAI/xlm-clm-enfr-1024\")\n",
    "model = XLMWithLMHeadModel.from_pretrained(\"FacebookAI/xlm-clm-enfr-1024\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "L'attributo `lang2id` del tokenizer mostra il linguaggio del modello e il suo ids:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'en': 0, 'fr': 1}"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(tokenizer.lang2id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Poi, crea un esempio di input:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_ids = torch.tensor([tokenizer.encode(\"Wikipedia was used to\")])  # batch size of 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Imposta l'id del linguaggio a `\"en\"` e usalo per definire il language embedding. Il language embedding è un tensore riempito con `0` perché questo è il language id per l'inglese. Questo tensore dovrebbe avere la stessa dimensione di `input_ids`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "language_id = tokenizer.lang2id[\"en\"]  # 0\n",
    "langs = torch.tensor([language_id] * input_ids.shape[1])  # torch.tensor([0, 0, 0, ..., 0])\n",
    "\n",
    "# We reshape it to be of size (batch_size, sequence_length)\n",
    "langs = langs.view(1, -1)  # is now of shape [1, sequence_length] (we have a batch size of 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Adesso puoi inserire `input_ids` e language embedding nel modello:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "outputs = model(input_ids, langs=langs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lo script [run_generation.py](https://github.com/huggingface/transformers/tree/main/examples/pytorch/text-generation/run_generation.py) può generare testo tramite i language embeddings usando i checkpoints `xlm-clm`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### XLM senza language embeddings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I seguenti modelli XLM non richiedono l'utilizzo dei language embeddings per fare inferenza:\n",
    "\n",
    "- `FacebookAI/xlm-mlm-17-1280` (Modellazione mascherata del linguaggio, 17 lingue)\n",
    "- `FacebookAI/xlm-mlm-100-1280` (Modellazione mascherata del linguaggio, 100 lingue)\n",
    "\n",
    "Questi modelli sono utilizzati per rappresentazioni generiche di frasi, a differenza dei precedenti checkpoints XML."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## BERT"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Il seguente modello BERT può essere usato per compiti multilingue:\n",
    "\n",
    "- `google-bert/bert-base-multilingual-uncased` (Modellazione mascherata del linguaggio + Previsione della prossima frase, 102 lingue)\n",
    "- `google-bert/bert-base-multilingual-cased` (Modellazione mascherata del linguaggio + Previsione della prossima frase, 104 lingue)\n",
    "\n",
    "Questi modelli non richiedono language embeddings per fare inferenza. Riescono ad identificare il linguaggio dal contesto e inferire di conseguenza."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## XLM-RoBERTa"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Il seguente modello XLM-RoBERTa può essere usato per compiti multilingue:\n",
    "\n",
    "- `FacebookAI/xlm-roberta-base` (Modellazione mascherata del linguaggio, 100 lingue)\n",
    "- `FacebookAI/xlm-roberta-large` (Modellazione mascherata del linguaggio, 100 lingue)\n",
    "\n",
    "XLM-RoBERTa è stato addestrato su 2.5TB di dati CommonCrawl appena creati e puliti in 100 lingue. Offre notevoli vantaggi rispetto ai modelli multilingue rilasciati in precedenza, come mBERT o XLM, in compiti come la classificazione, l'etichettatura delle sequenze e la risposta alle domande."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## M2M100"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Il seguente modello M2M100 può essere usato per compiti multilingue:\n",
    "\n",
    "- `facebook/m2m100_418M` (Traduzione)\n",
    "- `facebook/m2m100_1.2B` (Traduzione)\n",
    "\n",
    "In questo esempio, carica il checkpoint `facebook/m2m100_418M`  per tradurre dal cinese all'inglese. Puoi impostare la lingua di partenza nel tokenizer:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from transformers import M2M100ForConditionalGeneration, M2M100Tokenizer\n",
    "\n",
    "en_text = \"Do not meddle in the affairs of wizards, for they are subtle and quick to anger.\"\n",
    "chinese_text = \"不要插手巫師的事務, 因為他們是微妙的, 很快就會發怒.\"\n",
    "\n",
    "tokenizer = M2M100Tokenizer.from_pretrained(\"facebook/m2m100_418M\", src_lang=\"zh\")\n",
    "model = M2M100ForConditionalGeneration.from_pretrained(\"facebook/m2m100_418M\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Applica il tokenizer al testo:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "encoded_zh = tokenizer(chinese_text, return_tensors=\"pt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "M2M100 forza l'id della lingua obiettivo come primo token generato per tradurre nella lingua obiettivo. Imposta il parametro `forced_bos_token_id` a `en` nel metodo `generate` per tradurre in inglese:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Do not interfere with the matters of the witches, because they are delicate and will soon be angry.'"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "generated_tokens = model.generate(**encoded_zh, forced_bos_token_id=tokenizer.get_lang_id(\"en\"))\n",
    "tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## MBart"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Il seguente modello MBart può essere usato per compiti multilingue:\n",
    "\n",
    "- `facebook/mbart-large-50-one-to-many-mmt` (Traduzione automatica multilingue uno-a-molti, 50 lingue)\n",
    "- `facebook/mbart-large-50-many-to-many-mmt` (Traduzione automatica multilingue molti-a-molti, 50 lingue)\n",
    "- `facebook/mbart-large-50-many-to-one-mmt` (Traduzione automatica multilingue molti-a-uno, 50 lingue)\n",
    "- `facebook/mbart-large-50` (Traduzione multilingue, 50 lingue)\n",
    "- `facebook/mbart-large-cc25`\n",
    "\n",
    "In questo esempio, carica il checkpoint `facebook/mbart-large-50-many-to-many-mmt` per tradurre dal finlandese all'inglese. Puoi impostare la lingua di partenza nel tokenizer:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from transformers import AutoTokenizer, AutoModelForSeq2SeqLM\n",
    "\n",
    "en_text = \"Do not meddle in the affairs of wizards, for they are subtle and quick to anger.\"\n",
    "fi_text = \"Älä sekaannu velhojen asioihin, sillä ne ovat hienovaraisia ja nopeasti vihaisia.\"\n",
    "\n",
    "tokenizer = AutoTokenizer.from_pretrained(\"facebook/mbart-large-50-many-to-many-mmt\", src_lang=\"fi_FI\")\n",
    "model = AutoModelForSeq2SeqLM.from_pretrained(\"facebook/mbart-large-50-many-to-many-mmt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Applica il tokenizer sul testo:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "encoded_en = tokenizer(en_text, return_tensors=\"pt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "MBart forza l'id della lingua obiettivo come primo token generato per tradurre nella lingua obiettivo. Imposta il parametro `forced_bos_token_id` a `en` nel metodo `generate` per tradurre in inglese:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"Don't interfere with the wizard's affairs, because they are subtle, will soon get angry.\""
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "generated_tokens = model.generate(**encoded_en, forced_bos_token_id=tokenizer.lang_code_to_id(\"en_XX\"))\n",
    "tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Se stai usando il checkpoint `facebook/mbart-large-50-many-to-one-mmt`, non hai bisogno di forzare l'id della lingua obiettivo come primo token generato altrimenti l'uso è lo stesso."
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 4
}
